Skip to content

iam: implement substrate neutral policy document model#327

Merged
sandeepvinayak merged 1 commit intosalesforce:mainfrom
SriramGuduri:iam_policy_doc
Mar 10, 2026
Merged

iam: implement substrate neutral policy document model#327
sandeepvinayak merged 1 commit intosalesforce:mainfrom
SriramGuduri:iam_policy_doc

Conversation

@SriramGuduri
Copy link
Contributor

Summary

< Provide a brief description of the changes in this PR >

Some conventions to follow

  1. add the module name as a prefix
    • for example: add a prefix: docstore: for document store module, blobstore for Blob Store module
  2. for a test only PR, add test:
  3. for a perf improvement only PR, add perf:
  4. for a refactoring only PR, add "refactor:"

@SriramGuduri SriramGuduri force-pushed the iam_policy_doc branch 3 times, most recently from 7b1e45d to 4bc6d1e Compare March 5, 2026 05:35
@codecov-commenter
Copy link

codecov-commenter commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 92.02658% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.36%. Comparing base (5a56444) to head (6149ad0).

Files with missing lines Patch % Lines
...ce/multicloudj/iam/aws/AwsIamPolicyTranslator.java 91.30% 8 Missing and 4 partials ⚠️
...a/com/salesforce/multicloudj/iam/model/Action.java 78.12% 3 Missing and 4 partials ⚠️
...ce/multicloudj/iam/gcp/GcpIamPolicyTranslator.java 94.23% 1 Missing and 2 partials ⚠️
...om/salesforce/multicloudj/iam/model/Statement.java 90.00% 0 Missing and 1 partial ⚠️
...ava/com/salesforce/multicloudj/iam/gcp/GcpIam.java 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #327      +/-   ##
============================================
+ Coverage     82.06%   82.36%   +0.30%     
- Complexity      553      625      +72     
============================================
  Files           183      191       +8     
  Lines         11238    11503     +265     
  Branches       1498     1525      +27     
============================================
+ Hits           9222     9475     +253     
- Misses         1351     1357       +6     
- Partials        665      671       +6     
Flag Coverage Δ
unittests 82.36% <92.02%> (+0.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +419 to +425
.statement(Statement.builder()
.sid("StorageReadAccess")
.effect("Allow")
.action("storage:GetObject")
.action("storage:ListBucket")
.resource("storage://demo-bucket/*")
.build())
Copy link
Contributor

@sharatchandrag sharatchandrag Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client code will be much clean and compact, Please explore the below inputs:

Can we enable validations by exploring the enums way of setting up the effect, actions and other properties

Something like this or a better way you can think of

Statement.builder()
    .effect(Effect.ALLOW)
    .action(StorageActions.GET_OBJECT)
    .action(StorageActions.PUT_OBJECT)
    .build()


public final class Action {
    private final String service;
    private final String operation;

    private Action(String service, String operation) {
        this.service = service;
        this.operation = operation;
    }

    public static Action of(String action) {
        // parses "storage:GetObject" → service="storage", operation="GetObject"
        // validates format
    }
}

public final class StorageActions {
    public static final Action GET_OBJECT = Action.of("storage:GetObject");
    public static final Action PUT_OBJECT = Action.of("storage:PutObject");
    public static final Action ALL = Action.wildcard("storage");
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1.

private static final String REGION = "us-central-1";
private static final String TENANT_ID = "projects/substrate-sdk-gcp-poc1";
private static final String SERVICE_ACCOUNT = "serviceAccount:multicloudjexample@substrate-sdk-gcp-poc1.iam.gserviceaccount.com";
private static final String SERVICE_ACCOUNT = "serviceAccount:chameleon@substrate-sdk-gcp-poc1.iam.gserviceaccount.com";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid hardcoding specific GCP service account identifiers (like chameleon@...) directly in the codebase. Since this is an open-source project, we shouldn't expose internal project IDs or account details.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

private static String translateAction(String action) {
// Handle wildcard actions (e.g., storage:*, compute:*, iam:*)
if (action.endsWith(":*")) {
String service = action.substring(0, action.length() - 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a case-sensitive check. Do we want to use .toLowerCase() here just in case to match the service name ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

case "iam":
return "iam:*";
default:
throw new SubstrateSdkException(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : UnknownException ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been using UnknownException for Server Side exceptions. Probably UnSupportedOperationException is a close fit rather.

// Handle specific actions
String awsAction = ACTION_MAPPINGS.get(action);
if (awsAction == null) {
throw new SubstrateSdkException(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : UnknownException ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been using UnknownException for Server Side exceptions. Probably UnSupportedOperationException is a close fit rather.

}

// Add Effect
awsStatement.put("Effect", statement.getEffect());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike Sid, the Effect field is mandatory in AWS IAM. Currently, if statement.getEffect() is null or empty, we are putting a null/empty value into the map, which will result in an invalid AWS policy.

We should add a null check here and either throw a valid Exception (as defined in your Javadoc) or provide a sensible default if the substrate-neutral format allows it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

Map<String, Object> awsStatement = new LinkedHashMap<>();

// Add Sid if present
if (statement.getSid() != null && !statement.getSid().isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We are calling statement.getSid() three times here. While the null check is safely handled by the && short-circuit, it’s cleaner to assign the SID to a local variable first. This avoids redundant method calls and makes the logic easier to follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack.

awsStatement.put("Effect", statement.getEffect());

// Translate and add Principals if present
if (statement.getPrincipals() != null && !statement.getPrincipals().isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Same as above comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

@SriramGuduri SriramGuduri force-pushed the iam_policy_doc branch 5 times, most recently from bd3dd79 to 78c1570 Compare March 10, 2026 06:23
@sandeepvinayak sandeepvinayak merged commit 03f6a8c into salesforce:main Mar 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants